package com.lbssoft.gpsbd.aspect;

import com.alibaba.fastjson.JSON;
import com.lbssoft.datalink.EntityManager;
import com.lbssoft.datalink.entity.SyncDevice;
import com.lbssoft.datalink.entity.SyncGroup;
import com.lbssoft.datalink.util.Log;
import com.lbssoft.gpsbd.common.Constant;
import com.lbssoft.gpsbd.common.ErrorEnum;
import com.lbssoft.gpsbd.common.Utils;
import com.lbssoft.gpsbd.dao.DeviceMapper;
import com.lbssoft.gpsbd.dao.GroupMapper;
import com.lbssoft.gpsbd.datalink.Context;
import com.lbssoft.gpsbd.model.Device;
import com.lbssoft.gpsbd.model.Group;
import com.lbssoft.gpsbd.model.Result;
import com.lbssoft.gpsbd.model.vo.Move;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Map;


@Aspect
@Component
public class SyncGroupAspect {
    //使用org.slf4j.Logger,这是Spring实现日志的方法
    private final static Logger logger = LoggerFactory.getLogger(SyncGroupAspect.class);


    @Autowired
    GroupMapper groupMapper;

    @Autowired
    DeviceMapper deviceMapper;

    /**
     * 定义AOP扫描路径
     * 第一个注解只扫描aopTest方法
     */
    @Pointcut("execution(public * com.lbssoft.gpsbd.controller.GroupController.add(..)) || " +
            "execution(public * com.lbssoft.gpsbd.controller.GroupController.delete(..)) || " +
            "execution(public * com.lbssoft.gpsbd.controller.GroupController.update(..)) || " +
            "execution(public * com.lbssoft.gpsbd.controller.GroupController.move(..))")
    public void group(){}

    /**
     * 记录HTTP请求开始时的日志
     */
    @Before("group()")
    public void doBefore(JoinPoint joinPoint){
    }

    /**
     * 记录HTTP请求结束时的日志
     */
    @After("group()")
    public void doAfter(){
    }

    /**
     * 获取返回内容
     * @param object
     */
    @AfterReturning(returning = "object",pointcut = "group()")
    public void doAfterReturn(Object object){
    }

    /**
     * 环绕通知（Around advice） ：包围一个连接点的通知，类似Web中Servlet规范中的Filter的doFilter方法。可以在方法的调用前后完成自定义的行为，也可以选择不执行。
     * @param joinPoint
     */
    @Around("group()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable
    {
        com.lbssoft.datalink.model.Result res = new com.lbssoft.datalink.model.Result();
        Group group = new Group();
        Group localGroup;
        SyncGroup syncGroup = new SyncGroup();
        Group parentGroup;
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Object[] args = joinPoint.getArgs();
        Method method = signature.getMethod(); //获取被拦截的方法
        String methodName = method.getName(); //获取被拦截的方法名
        //判断是否开启同步
        if (!Constant.DEV_MODE) {
            System.out.println("====同步开始=====");
            switch (methodName) {
                //添加分组
                case "add":
                    group = (Group) args[0];
                    System.out.println("group="+ JSON.toJSONString(group));
                    syncGroup.setName(group.getName());
                    if(group.getGroupId()!=null){
                        parentGroup = groupMapper.getGroupById(group.getGroupId());
                        if(parentGroup!=null){
                            syncGroup.setParentUUID(parentGroup.getUuid());
                        }
                    }

                    Log.info(JSON.toJSONString(syncGroup));
                    res = Context.entityManager.addGroup(syncGroup);
                    Log.info(JSON.toJSONString(res));
                    if (res.getCode() != 0) {
                        return new Result(ErrorEnum.E_005.getErrorCode(), ErrorEnum.E_005.getErrorMsg(), "");
                    }
                    group.setUuid(((Map)res.getData()).get("uuid").toString());
                    break;
                case "delete":
                    localGroup = groupMapper.getGroupById((int)args[0]);
                    if(localGroup==null){
                        return new Result(ErrorEnum.E_002.getErrorCode(), ErrorEnum.E_002.getErrorMsg(), "");
                    }
                    res = Context.entityManager.delGroup(localGroup.getUuid());
                    if (res.getCode() != 0) {
                        return new Result(ErrorEnum.E_005.getErrorCode(), ErrorEnum.E_005.getErrorMsg(), "");
                    }
                    break;
                //修改分组
                case "update":
                    group = (Group) args[0];
                    localGroup = groupMapper.getGroupById(group.getId());
                    syncGroup.setUuid(localGroup.getUuid());
                    syncGroup.setName(group.getName());
                    parentGroup = groupMapper.getGroupById(group.getGroupId());
                    if(parentGroup!=null){
                        syncGroup.setParentUUID(parentGroup.getUuid());
                    }
                    res = Context.entityManager.updateGroup(syncGroup);
                    if (res.getCode() != 0) {
                        return new Result(ErrorEnum.E_005.getErrorCode(), ErrorEnum.E_005.getErrorMsg(), "");
                    }
                    break;
                //移动到分组
                case "move":
                    Move move = (Move) args[0];
                    //分组移动到分组
                    if(move.getType().equals("group")){
                        localGroup = groupMapper.getGroupById(move.getId());
                        syncGroup.setUuid(localGroup.getUuid());
                        syncGroup.setName(localGroup.getName());
                        parentGroup = groupMapper.getGroupById(move.getGroupId());
                        if(parentGroup!=null){
                            syncGroup.setParentUUID(parentGroup.getUuid());
                        }
                        res = Context.entityManager.updateGroup(syncGroup);
                    //设备移动到分组
                    }else if(move.getType().equals("device")){

                        Device localDevice = deviceMapper.getDeviceById(move.getId());
                        SyncDevice syncDevice = new SyncDevice();
                        if(move.getGroupId()!=null&&move.getGroupId()!=0){
                            Group group1= groupMapper.getGroupById(move.getGroupId());
                            syncDevice.setGroupUUID(group1.getUuid());
                        }
                        syncDevice.setUuid(localDevice.getUuid());
                        Log.info(JSON.toJSONString(syncDevice));
                        res = Context.entityManager.updateDevice(syncDevice);
                    }

                    if (res.getCode() != 0) {
                        return new Result(ErrorEnum.E_005.getErrorCode(), ErrorEnum.E_005.getErrorMsg(), "");
                    }
                    break;
                default:

            }
            System.out.println("=====同步结束=====");
        }


        return  joinPoint.proceed();
    }

}